package com.java.jvalidator.framework.config;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.java.jvalidator.framework.ErrorMsg;
import com.java.jvalidator.framework.ValidationException;
import com.java.jvalidator.framework.ValidationExceptionMsg;
import com.java.jvalidator.framework.ValidationResult;
import com.java.jvalidator.framework.validator.AbstractCustomValidator;

class PropertyConfig {
	private List<RuleConfig> rules;
	private String propertyName;
	private String targetClassName;

	PropertyConfig(String className, String fieldName) {
		this.targetClassName = className;
		this.propertyName = fieldName;
		this.rules = new ArrayList<RuleConfig>();
	}

	ValidationResult validate(Object target) throws ValidationException {
		if (!target.getClass().getName().equals(this.targetClassName)) {
			throw new ValidationException(ValidationExceptionMsg.CLASS_NAME_NOT_EQUAL_ERROR);
		}
		ValidationResult result = new ValidationResult();

		// if (this.rules.size() == 0) {
		// Object property = TypeUtil.getPropertyValue(target,
		// this.propertyName);
		// if (property == null) {
		// return result;
		// }
		// Object obj;
		// if (property.getClass().isArray()) {
		// int length = Array.getLength(property);
		// for (int i = 0; i < length; i++) {
		// obj = Array.get(property, i);
		// result.addResult(ValidationFacade.getInstance().validateInSession(obj));
		// }
		// } else if ((property instanceof Collection)) {
		// Collection<?> collect = (Collection<?>) property;
		// Iterator<?> ite = collect.iterator();
		// while (ite.hasNext()) {
		// obj = ite.next();
		// result.addResult(ValidationFacade.getInstance().validateInSession(obj));
		// }
		//
		// // for (obj = collect.iterator(); ((Iterator)obj).hasNext(); ) {
		// // Object tempObj = ((Iterator) obj).next();
		// // result.addResult(ValidationFacade.getInstance()
		// // .validateInSession(tempObj));
		// // }
		// } else {
		// result.addResult(ValidationFacade.getInstance().validateInSession(property));
		// }
		// return result;
		// }

		for (int ruleIndex = 0; ruleIndex < this.rules.size(); ruleIndex++) {
			RuleConfig ruleConfig = this.rules.get(ruleIndex);

			if ((result.getErrorMsg().size() > 0) && (!ruleConfig.isMultiError())) {
				continue;
			}

			ErrorMsg errorMsg = ruleConfig.validate(target);
			if ((ruleConfig.getValidator() instanceof AbstractCustomValidator)) {
				// 如果当前校验器是自定义校验的话，需要取得自定义校验的errormsg
				AbstractCustomValidator customValidator = (AbstractCustomValidator) ruleConfig.getValidator();
				List<ErrorMsg> errorMsgs = customValidator.getErrorMsg();
				if ((errorMsgs != null) && (errorMsgs.size() > 0)) {
					result.addErrorMsg(errorMsgs);
				}
			} else if (errorMsg != null) {
				result.addErrorMsg(errorMsg);
			}
		}

		return result;
	}

	void addRule(RuleConfig rule) throws ValidationException {
		if (rule == null) {
			return;
		}
		if (!this.propertyName.equals(rule.getFieldName())) {
			throw new ValidationException(ValidationExceptionMsg.FIELD_NAME_NOT_EQUAL);
		}
		if (!this.targetClassName.equals(rule.getTargetClassName())) {
			throw new ValidationException(ValidationExceptionMsg.CLASS_NAME_NOT_EQUAL_ERROR);
		}
		this.rules.add(rule);
	}

	void configCustomValidator(String customValidatorClassName, Parameters params) throws ValidationException {
		Iterator<RuleConfig> ruleIter = this.rules.iterator();
		while (ruleIter.hasNext()) {
			RuleConfig rule = (RuleConfig) ruleIter.next();
			if (rule.getValidator() == null) {
				continue;
			}
			if (rule.getValidator().getClass().getName().equals(customValidatorClassName)) {
				rule.configCustomValidator(params);
				return;
			}
		}
		throw new ValidationException(ValidationExceptionMsg.CUSTOM_VALIDATOR_NOT_FOUND_ERROR + customValidatorClassName);
	}

	void setPlaceHolderValues(String errorMsgName, String[] strings) {
		if (errorMsgName == null) {
			return;
		}
		for (RuleConfig rule : this.rules) {
			if (errorMsgName.equals(rule.getErrorMsgName())) {
				rule.setPlaceHolderValues(strings);
			}
		}
	}

	String getTargetClassName() {
		return this.targetClassName;
	}

	String getPropertyName() {
		return this.propertyName;
	}
}
